const app = require('express')();
const fs = require('fs');
const path = require('path');
const http = require('../../utils/http');
const emitter = require('../../utils/events');
const { readExcelFile, writeExcelFile } = require('../../utils/excelFile');

// 页面基础地址
let baseURL =
  'https://www.alibaba.com/trade/search?indexArea=IndexArea=product_en&Country=TW,HK,VN,IN,CN&tab=supplier&f0=y';

// 等待时间
function sleep(time) {
  return new Promise(reslove => setTimeout(reslove, time));
}

// 爬虫页面基本逻辑
// 第一次有数据则则直接返回出去
// 后面看中介有数据没，没数据直接大半折
// 有数据取有数据到和没数据中半折
// 终止条件是

// 判断目录是否单文件
function isDirOne(dirname) {
  return fs.promises.readdir(dirname).then(files => {
    return files.length === 1;
  });
}

// 读取目录中第一个文件
function readOneFile(dirname) {
  return fs.promises.readdir(dirname).then(files => {
    return files[0];
  });
}

async function handleExcelData(data) {
  // 存放最终查找数据
  const excelData = [];
  // 第一个数据
  let index = 0;
  let count = data.length; // excel 数据总数
  let lastTitle = '';
  findFinalPage(data[index][0], data[index][1]); // 第一条数据开始查找
  // 查找最终页面函数
  async function findFinalPage(title, currentPage, lastPage = Infinity) {
    const url = `${baseURL}&SearchText=${title}&page=${currentPage}`;
    // console.log('当前查询的页面：', currentPage);
    currentPage = Number(currentPage);
    // 进行备份处理
    if (excelData.length && lastTitle !== title && excelData.length % 2 == 0) {
      // 备份数据写入表格
      emitter.emit('backup_event', `当前备份数据${excelData.length} 份，存放文件夹在 output 中!!`);
      writeExcelFile(excelData);
    }
    if (lastTitle !== title) {
      lastTitle = title;
    }
    try {
      await sleep(800); // 等待时间
      const $ = await http(url); // 获取页面
      emitter.emit('search_event', url);
      const { length } = $('#root').find('span'); // 查找条件
      if (lastPage && currentPage > 20) {
        // 计算两次差值
        let diff = 0;
        if (isFinite(lastPage)) {
          diff = Math.abs(lastPage - currentPage);
        } else {
          diff = Math.abs(currentPage);
        }
        // 查看是否存在
        if (length) {
          if (Math.floor(diff) <= 2) {
            console.log('接近要查找的真相1', lastPage, currentPage);
            findFinalPage(title, currentPage + 1, null); // 递归进行传入上次查找页数
          } else {
            const nextPage = currentPage + Math.floor(diff / 2);
            console.log(
              '存在向上',
              '上次查询',
              lastPage,
              '当前查询',
              currentPage,
              '下次查询',
              nextPage
            );
            findFinalPage(title, nextPage, currentPage);
          }
        } else {
          if (lastPage > currentPage) {
            // 向下查找
            const nextPage = currentPage - Math.floor(diff / 2);
            console.log(
              '不存在向下',
              '上次查询页',
              lastPage,
              '当前查询页',
              currentPage,
              '下次查询页',
              nextPage
            );
            findFinalPage(title, nextPage, currentPage); // 递归向下查找页数
          } else if (Math.floor(diff) <= 2) {
            console.log('接近要查找的真相2', lastPage, currentPage);
            findFinalPage(title, currentPage - 1, null); // 递归进行传入上次查找页数
          } else {
            // 向上查找
            const nextPage = lastPage + Math.floor(diff / 2);
            console.log(
              '不存在向上',
              '上次查询页',
              lastPage,
              '当前查询页',
              currentPage,
              '下次查询页',
              nextPage
            );
            findFinalPage(title, nextPage, currentPage); // 递归向上查找页数
          }
        }
      } else {
        // 说明还有数据
        if (length > 0) {
          findFinalPage(title, currentPage + 1, null);
        } else {
          // 小于10条不保证最终结果
          if (currentPage > 20) {
            excelData.push([
              title,
              `${baseURL}&SearchText=${title}&page=${currentPage - 1}`,
              currentPage - 1
            ]);
          } else {
            excelData.push([
              title,
              `${baseURL}&SearchText=${title}&page=${currentPage - 1}`,
              currentPage - 1,
              'ensure'
            ]);
          }
          // 发送事件
          emitter.emit('number_event', excelData.length);
          index++;
          if (index < count) {
            findFinalPage(data[index][0], data[index][1]);
          } else {
            emitter.emit('success_event', '数据全部爬取成功!!');
            // 数据写入表格
            writeExcelFile(excelData);
            // console.log('全部结束', 11);
          }
        }
      }
    } catch (err) {
      index++; // 下一条
      // 添加错误数据
      excelData.push([
        title,
        `${baseURL}&SearchText=${title}&page=${currentPage - 1}`,
        currentPage - 1,
        err.toString()
      ]);
      // 发送一条错误消息
      emitter.emit('error_event', url);
      // 判断是否结束
      if (index < count) {
        // await sleep(1000);
        findFinalPage(data[index][0], data[index][1]); // 继续下一条数据
      } else {
        emitter.emit('success_event', '数据全部爬取成功!!');
        // 数据写入表格
        writeExcelFile(excelData);
        // console.log('全部结束', 22);
      }
    }
  }
}

// 处理爬虫
async function handleReptile(req, res) {
  const excelPath = path.join(__dirname, '../../../excel'); // 存储上传文件目录
  const isOneDir = await isDirOne(excelPath); // 目录中是否单文件
  if (!isOneDir) {
    return res.api_error('请重新上传文件在进行爬虫');
  }
  res.api_success(true, '正在努力的爬取数据！！！请稍等！！');
  // 后续处理
  const fileName = await readOneFile(excelPath); // 获取目录中文件
  const filePath = path.join(excelPath, fileName); // 上传目录完整路径
  const excelData = readExcelFile(filePath); // 读取上传 excel 数据
  handleExcelData(excelData);
}

app.post('/', (req, res) => handleReptile(req, res));

module.exports = app;
